home *** CD-ROM | disk | FTP | other *** search
-
- ___________________________________________________________________________
-
- CLPARSER.TPU Copyright (c) 1989-92 Greg Truesdell
- Version 3.2 a Turbo Pascal Object Unit
- ___________________________________________________________________________
-
-
- ABOUT THE AUTHOR___________________________________________________________
-
- The author is an Information Technology Specialist at the Education
- Development Centre in Burnaby, BC, Canada. The EDC is an industrial
- training and development facility which provides state-of-the-art CBT and
- instructor led courses to corporations and governments throught-out Canada,
- The United States, Europe, Middle East and Far East. As a member of the
- BC Tel Group of Companies, the EDC specializes in Telecommunications,
- Mainframe Computer, Personal Computer, Management, Engineering and Sales
- training as well as Educational Development Resources.
-
- The author was trained as an Aviation Electronics Tech. in the US Navy and
- joined the British Columbia Telephone Co. in 1974. He held positions in
- Test Desk, Teletype/Data (computer maintenance) and Instructor of computer
- technology courses.
-
- The author is currently responsible for the design, implementation and
- support of Database and Office Automation Systems and products used by the
- EDC, and has co-produced their multi-user time tracking and shared project
- reporting system, the automated billing system, the VAX PCSA-based Office
- Automation multi-user menuing system, the information and report
- distribution system and the student registration and confirmation system.
-
- He is a member of a four person team responsible for all computer-based
- information services required by more than 150 networked PC users as well
- as over 100 mainframe SNA and direct access ports. Languages of choice
- are Clipper, dBase, Vax C, Turbo C and MS C, Turbo C++, Turbo Pascal and
- Assembler.
-
- He lives with his wife of 20 years, Julia, and their two sons, Joe (18)
- and Duncan (17). Many thanks to Julia for her MUCH patience!
-
-
- INTRODUCTION_______________________________________________________________
-
- CLParser.TPU is a Command Line Parser. It provides the programmer with
- several pre-defined objects for dealing with command line options and
- switches. The unit also provides parsing for wildcard filenames, all
- environment variables and simple text parameter files.
-
- The unit provides methods which manipulate lists of items. The primary
- object is CLPLIST. The following is the type definition for CLPLIST:
-
- ItemRecordP = ^ItemRecord;
- ItemRecord = Record
-
- Item :^String; { parsed item String }
- ItemLen : Byte; { length + 2 of item String }
- Posn : LongInt; { position }
- | Cargo : Pointer; { data record pointer }
- | CargoLen : LongInt; { size of data record pointer }
- NextItem : ItemRecordP; { pointer to the next node in list }
- PrevItem : ItemRecordP; { pointer to previous node in list }
-
- end;
-
- { list is the data structure }
- pClpList = ^clpList;
- clpList = object
-
- firstitem : ItemRecordP; { pointer to first record in list }
- currentitem : ItemRecordP; { pointer to current record in list }
- lastitem : ItemRecordP; { pointer to last record in list}
- items : Word; { number of items in the list }
- index : Word; { current item number }
-
- Constructor Init;
- Destructor Done;
- Function Add( add_item: String; locn: LongInt ): Boolean;
- | Function AddCargo( Add_Item: String; Locn: LongInt;
- | pCargo : Pointer; CargoSize: Word ) : Boolean;
- Function Next: String;
- | Function NextCargo( var pCargo : Pointer; var CargoSize : LongInt ) : String;
- Function Prev: String;
- | Function PrevCargo( var pCargo : Pointer; var CargoSize : LongInt ) : String;
- Function Count: Word;
- Function Position: LongInt;
- Procedure Reset;
- end;
-
- { help is a list of help lines }
- pHelp = ^Help;
- Help = object(clpList)
- ScreenLines : Byte;
- LineCount : Byte;
-
- Constructor Init( nLines : Byte );
- Function ReadFile( filename : String ) : Boolean;
- Procedure Display;
- end;
-
- { argument is a list of arguments }
-
- pArgument = ^Argument;
- Argument = object(clpList)
-
- more : Boolean;
-
- Constructor Init( LegalChars: CharSet );
- Function Find( target : String ): String;
- Function Overflow: Boolean;
-
- end;
-
- { Environ is a list of environment variables }
-
- pEnviron = ^Environ;
- Environ = object(Argument)
-
- Constructor Init;
-
- end;
-
- { wild is a special list of filenames }
-
- { ======================================================== }
- { }
- { NOTE: The pWild object calls the AddCargo method using }
- { the search record returned by the FindFirst() and }
- { FindNext() DOS unit procedures. }
- { }
- { ======================================================== }
-
- pWild = ^Wild;
- Wild = object(argument)
-
- Constructor Init( filemask: String; attributes: Word );
-
- end;
-
- { pfile is a special list of parameter file entries }
- pPFile = ^PFile;
- PFile = object(argument)
-
- Constructor Init( filename: String; comment: CharSet );
-
- end;
-
-
- The CLPLIST object can be used to maintain any kind of sequential list of
- strings. Each item in the list is a pointer to a variable length string
- and a location word. The location word was primarily provided to register
- where, on the command line, the item was found. It may also be used to
- mark entries in the list for other reasons.
-
- Version 2.x was restricted to 1024 entries in any one of the objects. In
- version 3.x, no such restriction applies. The only restriction is the
- amount of available heap memory.
-
- Since all other objects in this unit are based on this object, and because
- none of these objects add any data instances of their own, the above
- paragraph is true for them also.
-
-
- The following is a list of all objects defined in CLPARSER.TPU:
-
- name(type) unique methods
- ----------- --------------------------------------------------------
- CLPLIST Init : Clear list to initial values (nil).
- (object) Done : Erase and reclaim memory used by the list.
- Add : Add an item to the list.
- | AddCargo : Add an item to the list with cargo.
- Next : Step forward and get next item.
- | NextCargo : Get next item with cargo.
- Prev : Step backward and get previous item.
- | PrevCargo : Get previous item with cargo.
- Count : Return the number of items in the list.
- Position : Return line position of this item.
- Reset : Reset the item pointer to the beginning.
- ----------- --------------------------------------------------------
- ARGUMENT Init : Fill array with valid arguments.
- (clplist) Find : Locate a specific argument.
- Overflow : Returns TRUE if there were more arguments
- than could fit in memory.
- ----------- --------------------------------------------------------
- WILD Init : Fill the array with filenames that match the
- (argument) filename mask.
- ----------- --------------------------------------------------------
- ENVIRON Init : Fill the array with all environment
- (argument) variables.
- ----------- --------------------------------------------------------
- PFILE Init : Fill the array with all parameters from a
- (argument) text parameter file.
- ----------- --------------------------------------------------------
-
- The CLPLIST object is the primary object. The ARGUMENT object inherits all
- of CLPLIST's methods except "Init", and adds two new methods; "Find" and
- "Overflow". The remaining objects (WILD, ENVIRON and PFILE) all inherit
- the methods from CLPLIST and ARGUMENT except "Init". Once you understand
- how to use CLPLIST and ARGUMENT, then you need only examine the difference
- in the "Init" methods for the remaining objects.
-
-
-
- HOW TO USE CLPARSER.TPU____________________________________________________
-
- To use CLPARSER, simply include the USES CLPARSER statement in your program
- header. You must also ensure that CLPARSER.TPU is placed in the directory
- | where you keep your units; usually \TP\UNITS. CLPARSER no longer automa-
- | tically parses the commandline for you when the program executes. You will
- | need to instantiate the object directly in your code. For example:
- |
- | Automatically instantiated:
- |
- | Var
- | Parse_Argument : Argument; {List of arguments from commandline}
- | Parse_Switch : Argument; {List of switches from commandline}
- | Begin
- | Parse_Argument.Init(NormalChars-Switches);
- | Parse_Switch.Init(Switches);
- | if Parse_Switch.Count > 0 then ...
- | ....
- | ....
- | Parse_Argument.Done;
- | Parse_Switch.Done;
- | End.
- |
- | Dynamically instantiated:
- |
- | Var
- | pArg, pSw : pArgument;
- | Begin
- | pArg := New( pArgument, Init( NormalChars-Switches ));
- | pSw := New( pArgument, Init( Switches ));
- | if pSw^.Count > 0 then ...
- | ....
- | ....
- | Dispose( pSw, Done );
- | Dispose( pArg, Done );
- | End.
- |
- | Other available objects are :
- |
- | Wild (pWild) : list of filenames and search records
- | Environ (pEnviron) : list of environment variables
- | PFile (pPFile) : list of parameter file items
- | Help (pHelp) : lines of help text.
-
- Data Structure Access Methods
-
- In the introduction section you will find a list of objects and unique
- methods associated with them. From that list you can see the data struct-
- ure access methods available for the ARGUMENT and SWITCH objects. Let's
- first examine the automatically initialized data structures.
-
-
- Examine this program:
-
- program CLParser_Sample;
-
- uses CLParser;
-
- var
- I : Integer;
- | pArg, pSw : pArgument;
-
- begin
- | pArg := New( pArgument, Init(NormalChars-Switches) );
- | pSw := New( pArgument, Init(Switches) );
- |
- | if pArg^.Count > 0 then
- begin
- | Write('There are ',pArg^.Count );
- WriteLn(' arguments on the command line.');
-
- | for I := 1 to pArg^.Count do
- | WriteLn( pArg^.Next );
-
- WriteLn('End of Arguments');
- end
- else WriteLn('There were NO arguments on the command line.');
-
- WriteLn;
-
- | if pSw^.Count > 0 then
- begin
- | Write('There are ',pSw^.Count );
- WriteLn(' arguments on the command line.');
-
- | for I := 1 to pSw^.Count do
- | WriteLn( pSw^.Next );
-
- WriteLn('End of Switches');
- end
- else WriteLn('There were NO switches on the command line.');
-
- | Dispose( pSw, Done );
- | Dispose( pArg, Done );
- end.
-
- When this program is compiled and executed, the two data structures are
- | initially filled with items. The unit determines which items on the
- command line are switches or arguments by checking the first character
- of the item.
-
- o Switches are items that begin with '/', '-' or '+'.
-
- o Arguments are items that begin with any normal character.
- Normal characters are [#32..#127].
-
-
- | The program executes:
- |
- | pArg := New( pArgument, Init(NormalChars-Switches) );
- |
- | and
- |
- | pSw := New( pArgument, Init(Switches) );
-
- when the program starts. The initialization method is passed the set of
- valid first characters for each data structure. In the example program
- above, the arguments listed would be any that do not start with a switch
- character but DO start with a normal character. All other items on the
- commandline are IGNORED!
-
- Assume you have compiled the example program as SAMPLE.EXE and typed:
-
- SAMPLE ONE TWO /A THREE -B +C FOUR
-
- The program would display:
-
- There are 4 arguments on the command line.
- ONE
- TWO
- THREE
- FOUR
-
- There are 3 switches on the command line.
- /A
- -B
- +C
-
- The methods used in the example are COUNT and NEXT. COUNT returns the
- number of items in the list. Parse_Argument.COUNT returns the number of
- arguments parsed from the command line. NEXT returns the next item in the
- list; Parse_Argument.NEXT returns the next argument from the list.
-
- examples:
-
- | Current_Position := pSw^.Position;
- | Next_Argument := pArg^.Next;
- | pSw^.Reset;
- | If pSw^.Add('SETUP.DAT',0) then .....
-
-
- Here is a list of available UNIQUE methods:
-
- | (Argument).Init( LegalChars: CharSet )
- | (Wild).Init( FileMask: string; Attributes: word )
- | (Environ).Init
- | (PFile).Init( Filename: string; Comment: CharSet )
-
-
-
- REFERENCE__________________________________________________________________
-
-
- Method: ADD( add_item: string; locn: byte ): BOOLEAN
-
- Type: Function
-
- Definition: The ADD method is used to add an item to the end of the
- list. If the ADD is successful, the function returns TRUE.
- Failure to ADD occurs only if there is not enough memory
- on the heap for a new item.
-
- The LOCN parameter is normally used with Parse_Argument and
- Parse_Switch to indicate where on the command line an item
- was found. It can be used by the programmer to supply a
- unique or special code to an item.
-
-
- Usage: If not pWild^.ADD('C:\COMMAND.COM',0)
- Then WriteLn('Not enough room!');
-
- ___________________________________________________________________________
-
- Method: COUNT: WORD
-
- Type: Function
-
- Definition: The COUNT method returns the number of items in the list.
- If the list is empty then COUNT returns 0.
-
- Usage: If pSw^.COUNT = 0 Then
- WriteLn('No Switches on the command line.');
-
- ___________________________________________________________________________
-
- Method: DONE
-
- Type: Destructor
-
- Definition: DONE will reclaim memory used by the list and reset all
- entries to nil.
-
- Usage: pEnviron^.DONE; ... or ...
-
- Dispose(pEnviron, DONE);
-
- ___________________________________________________________________________
-
- Method: FIND( target: string ): STRING
-
- Type: Function
-
- Definition: FIND is used to locate a given item in the list. If a match
- is found then FIND will return the matching item. If the
- target is shorter that the item compared, FIND will match
- partial string. ie. to find "/P=<filename>" use:
-
- Usage: Parameter_File := pSw^.FIND('/P=');
-
- If length(Parameter_File) > 0
- Then Filename := copy(Parameter_File,4,255)
- Else Filename := '';
- ___________________________________________________________________________
-
- Method: (Argument).INIT( LegalChars: CharSet )
-
- Type: Constructor
-
- Definition: This instance of INIT is used to fill the ARGUMENT list
- with items from the command line. LegalChars is a set
- of characters to be used as indicators of legal arguments.
-
- CLPARSER defaults to [#32..#127] - ['/','-','+'].
-
- WARNING! Do not use this command in your program until
- you have used pArg^.ERASE first! Since
- this command is automatically executed when your
- program starts, allocated memory would become
- trapped and unusable!
-
- Usage: pArg := New( pArgument, Init(['0'..'9']) )
- { scan for numbers only }
-
- ___________________________________________________________________________
-
- Method: (Environ).INIT
-
- Type: Constructor
-
- Definition: This instance of INIT fills the ENVIRON list with all
- environment variables that will fit. This is not an
- automatic-execution object. You MUST use this first
- before you can access the data structure.
-
- Usage: pEnv := New( pEnviron, INIT );
-
- ___________________________________________________________________________
-
- Method: (PFile).INIT( filename: string, Comment: CharSet )
-
- Type: Constructor
-
- Definition: This is one of the more interesting objects in this unit.
- If the file specified by filename is found, then it is
- parsed for items to be added to the list. White space
- before and after the item is stipped. Blank lines and
- comment lines are skipped. Comment lines are defined
- by the set of characters specified by Comment. Any line
- whose first non-white space (tab or space) character is
- in the Comment set of characters is skipped.
-
- Usage: Example Parameter File: PARM.DAT
-
- ; Sample Parameter file
-
- ************* User Data *************
-
- John Smith {1}
- Level=10 {2}
- Password=Not Now, Dear! {3}
-
- ************* System Data ***********
-
- Size=100 {4}
- Time=1:00 {5}
- Delay=1000 {6}
-
- ; end of parameter file
-
- Program example:
-
- pPF := New(pPFile, Init( 'PARM.DAT', [';','*'] );
-
- The {} numbers represent the position numbers in the list
- after execution. The list will contain only 6 items. All
- other line have been skipped.
-
- ___________________________________________________________________________
-
- Method: (pWild).INIT( filemask:string; attributes:word );
-
- Type: Constructor
-
- Definition: This method fills the WILD list with items (filenames) that
- that match the filename mask. This can build a potentially
- gigantic list. CLPARSER is limited only to the amount of
- heap memory available.
-
- The attributes parameter is identical to the attributes
- provided by Turbo's DOS unit.
-
- Usage: pW := New(pWild,INIT('*.DOC',ANYFILE-HIDDEN-VOLUMEID));
-
- ___________________________________________________________________________
-
- Method: NEXT: STRING
-
- Type: Function
-
- Definition: NEXT returns the next item in the list. If the last item
- has already been accessed, then NEXT returns an empty
- string. Use RESET to set the internal index back to the
- beginning of the list. Use PREV to return the previous
- item.
-
- Usage: Next_Item := pW^.NEXT;
-
- ___________________________________________________________________________
-
- Method: NEXTCARGO(var pCargo:Pointer; var CargoSize:LongInt): STRING
-
- Type: Function
-
- Definition: NEXTCARGO returns the next item in the list including the
- cargo information. If the last item has already been
- accessed, then NEXT returns an empty string. Use RESET to
- set the internal index back to the beginning of the list.
- Use PREVCARGO to return the previous item.
-
- Usage: Next_Item := pW^.NEXTCARGO( DataPtr, DataSize );
-
- ___________________________________________________________________________
-
- Method: OVERFLOW: BOOLEAN
-
- Type: Function
-
- Definition: Returns TRUE if INIT found more items than would fit in
- memory or in the list.
-
- Usage: If pW^.OVERFLOW
- Then WriteLn('Sorry, not enough space for all files!');
-
-
- ___________________________________________________________________________
-
- Method: POSITION: WORD
-
- Type: Function
-
- Definition: When used with Parse_Argument or Parse_Switch POSITION
- returns the position on the command line where the current
- item was found.
-
- Otherwise POSITION returns whatever value the programmer
- placed there with the ADD method.
-
- Usage: Current_Switch := pSw^.NEXT;
- If pSw^.POSITION < pArg^.POSITION
- Then WriteLn('Ambiguous use of ',Current_Switch);
-
- ___________________________________________________________________________
-
- Method: PREV: STRING
-
- Type: Function
-
- Definition: PREV backs up one entry and returns that item in the list.
- If already at the beginning, then PREV returns an empty
- string.
-
- Usage: Previous_Item := pEnv^.PREV;
-
- ___________________________________________________________________________
-
- Method: PREVCARGO(var pCargo:Pointer; var CargoSize:LongInt): STRING
-
- Type: Function
-
- Definition: PREV backs up one entry and returns that item in the list
- including cargo. If already at the beginning, then PREV
- returns an empty string.
-
- Usage: Previous_Item := pEnv^.PREV( DataPtr, DataSize );
-
- ___________________________________________________________________________
-
- Method: RESET
-
- Type: Procedure
-
- Definition: RESET simply resets the data structure's current entry
- index pointer to the beginning of the list.
-
- Usage: If pArg^.NEXT := '' then pArg^.RESET;
-
- ___________________________________________________________________________
-
-
-
- CHANGES IN VERSION 3.x_____________________________________________________
-
- Version 3.x represents a change in the data structure philosophy. When
- CLPARSER was orginally designed, I used it as an included unit that was
- compiled specifically for each project. The maximum number of command line
- switches and arguments was known at compile time, so the unit would be
- as small or large as required. No virtual methods were used, which allows
- the smart linker to do it's thing, and the pointer arrays were only as
- large as required.
-
- The decision to release CLPARSER for others required some thinking. It is
- my opinion now that the version released was in-ordinately wasteful of
- memory resources. Each instantiation required another 1024 pointers and
- 1024 bytes, whether it used them or not. I knew that, for myself, this
- would be un-acceptable.
-
- So; in Version 3.x NO memory (beyond the object itself) is used until an
- item is added to the list. Also there are NO virtual methods. These were
- removed to allow the smart linker to smart link and to provide EARLY
- binding of objects. These are a little faster and definately safer to
- use. The side effect is in inheritance. It is my opinion that CLPARSER
- is not a particularly good choice as a general list object. I take my
- hat off to Turbo Power's Object Professional as a source of good, general
- purpose, objects. So, "no virtual methods" is prefered in this type of
- object.
-
- If you have purchased the SOURCE LICENSE, then you can virtualize until
- you are blue in the face, if you wish.
-
- Nothing else has been added. Only natures pure ingredients were used.
-
-
-
- REGISTRATION_______________________________________________________________
-
-
- There is no charge for using this unit unless you are profitting from
- it's use or you want the source code. Commercial users MUST register
- irregardless of whether you sell software or not.
-
- This version of CLPARSER.TPU is currently available for Turbo Pascal 5.5
- and Turbo Pascal v6.0.
-
- Since the unit is in object format, you can make use of the primary objects
- in your own programs. You are free use this unit as is or as a basis for
- your own objects under the following restrictions:
-
- o Using CLParser.TPU for any commercial purpose, you must register
- for a single-site license fee of $12.00.
-
- o To use CLParser.TPU in a Public Domain release you must register.
- Registration is free, but handling is $5.00 if you want the
- distribution disk.
-
- o To use CLParser.TPU with your own personal programs, no registrat-
- ion is required.
-
- To obtain the source code you must register for a source-code license of
- $20.00. This license covers all above mentioned licenses.
-
- When registering, please remember to include your name, company name,
- address, city, state/province and postal code. You must also provide
- your signiture with a request for the source license.
-
- NOTE: Registration entitles you to a license for use. The software
- remains the intellectual property of the copyright holder.
-
- If you are paying for registration, send MONEY ORDERS ONLY, please.
-
- Greg L. Truesdell
- 36 Seaview Drive
- Port Moody, BC CANADA
- V3H 1N7
-
- Tel: (604) 939-1009
- CompuServe: 75360,1303
-
- ___________________________________________________________________________
-
- ___________________________________________________________________________
-
- CLParser v3.2 Registration Form 08/06/92
- ___________________________________________________________________________
-
- Remit to:
- Greg L. Truesdell
- 36 Seaview Drive
- Port Moody, BC CANADA
- V3H 1N7
-
- ┌──────────────────────────────────────────────────────┐
- │ Send MONEY ORDERS ONLY if ordering outside of Canada │
- └──────────────────────────────────────────────────────┘
-
- Registration Level
-
- [ ] Commercial Site License 12.00 _____________
-
- [ ] Public Domain Usage License 5.00 _____________
-
- [ ] Source Code License 20.00 _____________
-
- TOTAL _____________
-
-
- Name _____________________________________________________
-
- Company _____________________________________________________
-
- Address _____________________________________________________
-
- City ________________________________________ State\Prov ___________
-
- Zip\Postal Code ___________
-
- Telephone No. ( ) -
-
- ___________________________________________________________________________
-
- Complete if ordering a SOURCE CODE LICENSE
- ___________________________________________________________________________
-
-
- With my signature I certify that I will not disclose or distribute
- modified or un-modified copies of the source to CLPARSER, and that no
- modified copies of CLPARSER.TPU will be distributed in any form without
- express permission of the copyright holder. CLPARSER is the intellectual
- property of the copyright holder and, as such, is licensed for USE ONLY
- and remains the property of the copyright holder.
-
-
- Signature ______________________________________
- REQUIRED FOR SOURCE CODE LICENSE
-
- ___________________________________________________________________________
-
-
-
- ----------------end-of-author's-documentation---------------
-
- Software Library Information:
-
- This disk copy provided as a service of
-
- Public (software) Library
-
- We are not the authors of this program, nor are we associated
- with the author in any way other than as a distributor of the
- program in accordance with the author's terms of distribution.
-
- Please direct shareware payments and specific questions about
- this program to the author of the program, whose name appears
- elsewhere in this documentation. If you have trouble getting
- in touch with the author, we will do whatever we can to help
- you with your questions. All programs have been tested and do
- run. To report problems, please use the form that is in the
- file PROBLEM.DOC on many of our disks or in other written for-
- mat with screen printouts, if possible. PsL cannot debug pro-
- programs over the telephone, though we can answer questions.
-
- Disks in the PsL are updated monthly, so if you did not get
- this disk directly from the PsL, you should be aware that the
- files in this set may no longer be the current versions. Also,
- if you got this disk from another vendor and are having prob-
- lems, be aware that some files may have become corrupted or
- lost by that vendor. Get a current, working disk from PsL.
-
- For a copy of the latest monthly software library newsletter
- and a list of the 4,000+ disks in the library, call or write
-
- Public (software) Library
- P.O.Box 35705 - F
- Houston, TX 77235-5705
-
- 1-800-2424-PSL
- MC/Visa/AmEx/Discover
-
- Outside of U.S. or in Texas
- or for general information,
- Call 1-713-524-6394
-
-